﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data;
using System.Reflection;
using System.Globalization;

namespace UtilityLibrary.Ormapping
{
    public class AttributeAdapter : DataSource
    {
        public AttributeAdapter() : base() { }
        public AttributeAdapter(string connectionString) : base(connectionString) { }

        public DataTable Select(string strOrProc, IDataParameter[] parameters, CommandType type)
        {
            if (parameters != null)
            {
                DataBase.ClearParam();
                foreach (IDataParameter parameter in parameters)
                {
                    DataBase.MakeParam(parameter);
                }
            }
            switch (type)
            {
                case CommandType.StoredProcedure:
                    return DataBase.RunProcDataTable(strOrProc);

                case CommandType.Text:
                    return DataBase.RunSqlDataTable(strOrProc);
                default:
                    return null;
            }
        }

        public IList<TModel> Select<TModel>(DataTable dt)
        {
            //创建数据集
            IList<TModel> tModel = new List<TModel>();

            foreach (DataRow item in dt.Rows)
            {
                //创建对象实例
                Object obj = Activator.CreateInstance(typeof(TModel));
                if (typeof(TModel).IsPrimitive)
                {
                    obj = item[0];
                }
                else
                {
                    //为属性赋值
                    foreach (PropertyInfo p in typeof(TModel).GetProperties())
                    {
                        try
                        {
                            var value = new object();
                            try
                            {
                                if (!dt.Columns.Contains(p.Name) || item[p.Name] == DBNull.Value) continue;
                                Type t = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType;
                                value = Convert.ChangeType(item[p.Name], t, CultureInfo.CurrentCulture);
                            }
                            catch (Exception)
                            {
                                continue;
                            }
                            if (value != DBNull.Value)
                            {
                                p.SetValue(obj, value, null);
                            }
                        }
                        catch (IndexOutOfRangeException)
                        {

                        }
                    }
                }

                //加入集合
                tModel.Add((TModel)obj);
            }
            return tModel;
        }

        public IList<TModel> Select<TModel>(string strSql, IDataParameter[] parameters = null)
        {
            return Select<TModel>(Select(strSql, parameters, CommandType.Text));
        }

        public IList<TModel> ProcSelect<TModel>(string proc, IDataParameter[] parameters = null)
        {
            return Select<TModel>(Select(proc, parameters, CommandType.StoredProcedure));
        }

        public TModel GetDetails<TModel>(string strSql)
        {
            IList<TModel> list = Select<TModel>(strSql);
            if (list.Count <= 0) return default(TModel);

            return list[0];
        }

        public TModel GetDetails<TModel>(string strSql, IDataParameter[] parameters)
        {
            //创建参数
            DataBase.ClearParam();
            foreach (IDataParameter parameter in parameters)
            {
                DataBase.MakeParam(parameter);
            }
            return GetDetails<TModel>(strSql);
        }

        public TModel ProcGetDetails<TModel>(string proc)
        {
            IList<TModel> list = ProcSelect<TModel>(proc);
            if (list.Count <= 0) return default(TModel);

            return list[0];
        }

        public TModel ProcGetDetails<TModel>(string proc, IDataParameter[] parameters)
        {
            //创建参数
            DataBase.ClearParam();
            foreach (IDataParameter parameter in parameters)
            {
                DataBase.MakeParam(parameter);
            }
            return ProcGetDetails<TModel>(proc);
        }

        public int RunSql(string strSql)
        {
            DataBase.RunSql(strSql);
            return DataBase.ExecuteRowCount;
        }

        public int RunSql(string strSql, IDataParameter[] parameters)
        {
            //创建参数
            DataBase.ClearParam();
            foreach (IDataParameter parameter in parameters)
            {
                DataBase.MakeParam(parameter);
            }
            DataBase.RunSql(strSql);
            return DataBase.ExecuteRowCount;
        }

        public object RunSqlObject(string strSql)
        {
            return DataBase.RunSqlObject(strSql);
        }

        public object RunSqlObject(string strSql, IDataParameter[] parameters)
        {
            //创建参数
            DataBase.ClearParam();
            foreach (IDataParameter parameter in parameters)
            {
                DataBase.MakeParam(parameter);
            }
            return DataBase.RunSqlObject(strSql);
        }

        public int RunProc(string proc)
        {
            DataBase.RunProc(proc);
            return DataBase.ExecuteRowCount;
        }

        public int RunProc(string proc, IDataParameter[] parameters)
        {
            //创建参数
            DataBase.ClearParam();
            foreach (IDataParameter parameter in parameters)
            {
                DataBase.MakeParam(parameter);
            }
            DataBase.RunProc(proc);
            return DataBase.ExecuteRowCount;
        }

        public Object RunProcObject(string proc, IDataParameter[] parameters)
        {
            //创建参数
            DataBase.ClearParam();
            foreach (IDataParameter parameter in parameters)
            {
                DataBase.MakeParam(parameter);
            }
            return DataBase.RunProcObject(proc);
        }

        public IDataParameter CreateInput(string pName, object pValue)
        {
            return DataBase.CreateInput(pName, pValue);
        }

        public IDataParameter CreateInputOutput(string pName, object pValue)
        {
            return DataBase.CreateInputOutput(pName, pValue);
        }

        public IDataParameter CreateOutput(string pName, int pType)
        {
            return DataBase.CreateOutput(pName, pType);
        }

        public IDataParameter CreateOutput(string pName, int pType, int size)
        {
            return DataBase.CreateOutput(pName, pType, size);
        }

        public IDataParameter CreateReturnValue(string pName, int pType)
        {
            return DataBase.CreateReturnValue(pName, pType);
        }

        public IDataParameter CreateReturnValue(string pName, int pType, int size)
        {
            return DataBase.CreateReturnValue(pName, pType, size);
        }
    }
}
